package com.unlcn.ils.wms.backend.util;


import cn.huiyunche.commons.exception.BusinessException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

/**
 * @Author ：Ligl
 * @Date : 2017/5/11.
 */
public class HttpRequestUtil {


    private static Logger logger = LoggerFactory.getLogger(cn.huiyunche.commons.utils.HttpRequestUtil.class);

    //连接超时时间
    private static final int CONNECT_TIMEOUT = 10000;

    public static String sendHttpGet(final String url, final Map<String, Object> headerMap, final Map<String, Object> paramsMap, final int socketTimeout) throws Exception {

        CloseableHttpClient httpClient = HttpClients.createDefault();

        HttpGet httpGet = new HttpGet(url);
        if (!Objects.equals(headerMap, null) || !Objects.equals(headerMap, "")) {
            Iterator<Map.Entry<String, Object>> entries = headerMap.entrySet().iterator();
            while (entries.hasNext()) {
                Map.Entry<String, Object> entry = entries.next();
                String value = Objects.equals(entry.getValue(), null) || Objects.equals(entry.getValue(), "") ? "" : entry.getValue().toString();
                httpGet.addHeader(entry.getKey(), value);
            }
        }
        RequestConfig.Builder builder = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(socketTimeout);
        httpGet.setConfig(builder.build());

        try {
            CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
            return assemblyRetrunData(httpResponse);
        } catch (Exception e) {
            logger.error("HttpRequestUtil error : {}", e);
            throw new BusinessException(e.getMessage());
        } finally {
            // 关闭连接,释放资源
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String sendHttpPost(final String url, final Map<String, Object> headerMap, final Map<String, Object> paramsMap, final int socketTimeout) throws Exception {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        RequestConfig.Builder builder = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(socketTimeout);
        httpPost.setConfig(builder.build());
        List<NameValuePair> formParams = new ArrayList<NameValuePair>();
        if (null != paramsMap && !paramsMap.isEmpty()) {
            Set<String> set = paramsMap.keySet();
            Iterator<String> iterator = set.iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                Object value = paramsMap.get(key);
                formParams.add(new BasicNameValuePair(key, null == value ? null : value.toString()));
            }
        }
        if (null != headerMap && !headerMap.isEmpty()) {
            Set<String> set = headerMap.keySet();
            Iterator<String> iterator = set.iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                String value = Objects.equals(headerMap.get(key), null) || Objects.equals(headerMap.get(key), "") ? "" : headerMap.get(key).toString();
                httpPost.addHeader(key, value);
            }
        }
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
            CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
            return assemblyRetrunData(httpResponse);
        } catch (Exception e) {
            logger.error("HttpRequestUtil error : {}", e);
            throw new BusinessException(e.getMessage());
        } finally {
            // 关闭连接,释放资源
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static String assemblyRetrunData(CloseableHttpResponse httpResponse) {
        StatusLine statusLine = httpResponse.getStatusLine();
        if (200 == statusLine.getStatusCode()) {
            try {
                HttpEntity entity = httpResponse.getEntity();
                String resultData = entity != null ? EntityUtils.toString(entity) : null;
                if (StringUtils.isBlank(resultData)) {
                    logger.info("assemblyRetrunData is null");
                    throw new BusinessException("调用ERP无返回信息");
                }
                return resultData;
            } catch (IOException e) {
                logger.error("assemblyRetrunData error : {}", e);
                e.printStackTrace();
            } finally {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    logger.error("assemblyRetrunData error : {}", e);
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 接口调用 GET
     */
    public static void httpURLConectionGET(String getUrl) {
        try {
            URL url = new URL(getUrl);    // 把字符串转换为URL请求地址
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 打开连接
            connection.connect();// 连接会话
            // 获取输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {// 循环读取流
                sb.append(line);
            }
            br.close();// 关闭流
            connection.disconnect();// 断开连接
        } catch (Exception e) {
            logger.error("httpURLConectionGET error : {}", e);
            e.printStackTrace();
        }
    }

    /**
     * 接口调用  POST
     */
    public static String httpURLConnectionPOST(String postUrl, String params) {
        OutputStream output = null;
        InputStream input = null;
        String result = null;
        try {
            URL url = new URL(postUrl);
            // 将url 以 open方法返回的urlConnection  连接强转为HttpURLConnection连接  (标识一个url所引用的远程对象连接)
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 此时cnnection只是为一个连接对象,待连接中
            // 设置连接输出流为true,默认false (post 请求是以流的方式隐式的传递参数)
            connection.setDoOutput(true);
            // 设置连接输入流为true
            connection.setDoInput(true);
            // 设置请求方式为post
            connection.setRequestMethod("POST");
            // post请求缓存设为false
            connection.setUseCaches(false);
            // 设置该HttpURLConnection实例是否自动执行重定向
            connection.setInstanceFollowRedirects(true);
            // 设置请求头里面的各个属性 (以下为设置内容的类型,设置为经过urlEncoded编码过的from参数)
            // application/x-javascript text/xml->xml数据 application/x-Javascript->json对象 application/x-www-form-urlencoded->表单数据
            // ;charset=utf-8 必须要，不然妙兜那边会出现乱码【★★★★★】
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            // 建立连接 (请求未开始,直到connection.getInputStream()方法调用时才发起,以上各个参数设置需在此方法之前进行)
            connection.connect();
            //定义输出流
            output = connection.getOutputStream();
            if (StringUtils.isNotBlank(params)) {
                byte[] bytes = params.getBytes("utf-8");
                output.write(bytes, 0, bytes.length);
            }
            output.flush();
            //定义输入流，获取响应报文
            input = connection.getInputStream();
            result = IOUtils.toString(input, "UTF-8");
        } catch (Exception e) {
            logger.error("httpURLConnectionPOST  error:", e);
            e.printStackTrace();
        } finally {
            if (null != output)
                try {
                    output.close();
                } catch (IOException e) {
                    logger.error("httpURLConnectionPOST close output error:", e);
                    e.printStackTrace();
                }
            if (null != input)
                try {
                    input.close();
                } catch (IOException e) {
                    logger.error("httpURLConnectionPOST close input error:", e);
                    e.printStackTrace();
                }
        }
        return result;
    }
}
